package com.paper.tiger.easy.rpc.s.client.registy.common;

import com.alibaba.fastjson.JSON;
import com.paper.tiger.easy.rpc.core.RegisterData;
import com.paper.tiger.easy.rpc.core.Stub;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * [简要描述]:客户端存根
 * [详细描述]:
 *
 * @author ZouHaiBo
 * @version 1.0, 2021/6/16 15:43
 * @since JDK 1.8
 */
public class ServiceMessageData
{
    private static Logger logger = LoggerFactory.getLogger(ServiceMessageData.class);

    /**
     * key = 接口名称,value= 存根
     */
    private static Map<String, List<RegisterData>> interfaceNameStubs = new ConcurrentHashMap<>();

    /**
     * key = serviceName,value=注册数据
     */
    private static Map<String, List<RegisterData>> serviceNameDataMap = new ConcurrentHashMap<>();

    private static AtomicInteger count = new AtomicInteger(0);

    public static List<RegisterData> getByServiceName(String serviceName)
    {
        return serviceNameDataMap.get(serviceName);
    }

    /**
     * @param interfaceName
     * @return
     */
    public static Stub getByInterfaceName(String interfaceName)
    {
        List<RegisterData> messages = interfaceNameStubs.get(interfaceName);
        // todo 负载均衡
        int value = count.getAndAdd(1);
        int target = value % messages.size();
        RegisterData data = messages.get(target);
        return data.getList().get(0);
    }

    public static void add(RegisterData data, Channel channel)
    {
        List<Stub> list = data.getList();
        if (list == null || list.size() == 0)
        {
            return;
        }

        Map<String, List<Stub>> map = list.stream().collect(Collectors.groupingBy(e -> e.getAppName()));

        map.forEach((appName,stubs)->{

            Map<String, List<Stub>> hostKeyMap = stubs.stream().collect(Collectors.groupingBy(e -> e.getHostKey()));

            hostKeyMap.forEach((hostKey,stubList)->{


                List<RegisterData> dataList = serviceNameDataMap.get(appName);
                if (dataList == null)
                {
                    dataList = new CopyOnWriteArrayList<>();
                    serviceNameDataMap.put(appName, dataList);
                }
                Stub stub = stubList.get(0);
                RegisterData registerData = new RegisterData();
                registerData.setIp(stub.getIp());
                registerData.setAppName(stub.getAppName());
                registerData.setPort(stub.getPort());
                registerData.setList(stubList);
                dataList.add(registerData);



                List<RegisterData> messages = interfaceNameStubs.get(stub.getInterfaceClass());

                if (messages == null)
                {
                    messages = new CopyOnWriteArrayList<>();
                    interfaceNameStubs.put(stub.getInterfaceClass(), messages);
                }
                if (!messages.contains(registerData))
                {
                    messages.add(registerData);

                }

            });

        });


    }

    /**
     * 服务下线删除服务
     *
     * @param data
     * @param channel
     */
    public static void remove(RegisterData data,Channel channel)
    {
        String ip = data.getIp();
        Integer port = data.getPort();
        interfaceNameStubs.forEach((interfacaName, list) ->
        {

            Iterator<RegisterData> iterator = list.iterator();
            while (iterator.hasNext())
            {
                RegisterData next = iterator.next();
                if (next.getIp().equals(ip) && next.getPort().equals(port))
                {
                    iterator.remove();
                }
            }
        });
        logger.info("remove后的map为：{}", JSON.toJSONString(interfaceNameStubs));

        serviceNameDataMap.remove(data.getAppName());


    }

}
